package com.fingard.dsp.bank.directbank.fngrd01;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipaySystemOauthTokenRequest;
import com.alipay.api.response.AlipaySystemOauthTokenResponse;
import com.fingard.dsp.bank.directConfig.ActSetItem;
import com.fingard.dsp.bank.directbank.FailCode;
import com.fingard.dsp.bank.directbank.PaymentState;
import com.fingard.dsp.bank.directbank.bankInterface.IJSAPIOrder;
import com.fingard.dsp.bank.reqrespobj.unifiedorder.*;
import com.fingard.text.StringHelper;
import com.fingard.text.XmlHelper;

import java.net.URLEncoder;
import java.util.HashMap;

public class FnGrd01JSAPIOrder extends FnGrd01Base implements IJSAPIOrder {
    @Override
    public RetAtsUnifiedOrder submitJSAPIOrder(ReqUnifiedOrder p_req) {
        if ("WXJSAPI01".equals(p_req.reqHeader.commandCode) || "JSAPI01".equals(p_req.reqHeader.commandCode)) {
            return submitWXJSAPIOrder(p_req);
        } else if ("WXMiniProg01".equals(p_req.reqHeader.commandCode)) {
            return submitMiniProgOrder(p_req);
        } else {
            return submitALIPAYJSAPIOrder(p_req);
        }
    }

    public RetAtsUnifiedOrder submitWXJSAPIOrder(ReqUnifiedOrder p_req) {
        RetAtsUnifiedOrder retAts = new RetAtsUnifiedOrder();
        retAts.rdSeq = p_req.rdSeq;

        try {
            ActSetItem actItem = getBankConfig().getActSetItemByAny(p_req.ownAct, p_req.merchantId, p_req.appId, "unifiedorder");
            if (actItem == null) {
                retAts.respCode = "0";
                retAts.respInfo = "未找到账户、商户或公众号配置信息,请检查config.xml相关配置!";
                retAts.transState = PaymentState.FAIL;
                retAts.payInfoCode = FailCode.E9981;
                return retAts;
            }

            String openId = p_req.openid;
            if (StringHelper.isNullOrEmpty(openId)) {
                if (StringHelper.isNullOrEmpty(p_req.code)) {
                    retAts.respCode = "-1";
                    retAts.respInfo = "Code和Openid不能同时为空";

                    return retAts;
                } else {
                    if (StringHelper.isNullOrEmpty(actItem.appSecret)) {
                        retAts.respCode = "-1";
                        retAts.respInfo = "未配置公众号的appsecret";
                        return retAts;
                    } else {
                        HashMap<String, String> hashOpenid = getOpenid(actItem.appId, actItem.appSecret, p_req.code);

                        if (hashOpenid.get("RespCode").equals("0")) {
                            if (hashOpenid.containsKey("openid")) {
                                openId = hashOpenid.get("openid");
                            } else {
                                retAts.respCode = "-1";

                                String errcode = "";
                                if (hashOpenid.containsKey("errcode")) {
                                    errcode = hashOpenid.get("errcode");
                                }

                                String errmsg = "";
                                if (hashOpenid.containsKey("errmsg")) {
                                    errmsg = hashOpenid.get("errmsg");
                                }

                                retAts.respInfo = StringHelper.joinNotEmpty("-", errcode, errmsg);
                                return retAts;
                            }
                        } else {
                            retAts.respCode = "-1";
                            retAts.respInfo = hashOpenid.get("RespInfo");
                            return retAts;
                        }
                    }
                }
            }

            HashMap<String, String> mapParams = new HashMap<String, String>();

            mapParams.put("EnterpriseNum", actItem.inMerchantId);
            mapParams.put("MchId", actItem.merchantId);
            mapParams.put("AppId", actItem.appId);
            mapParams.put("OutTradeNo", p_req.rdSeq);
            mapParams.put("IsMiniPg", "0");
            mapParams.put("Body", XmlHelper.encode(p_req.description));
            mapParams.put("TotalFee", StringHelper.amountMultiply100(p_req.amount));
            mapParams.put("MchCreateIp", actItem.createIP);
            mapParams.put("NotifyUrl", actItem.notifyURL);

            String succBackUrl = "";
            String failBackUrl = "";
            if (StringHelper.hasAnyChar(actItem.getNotifyURLMap("wx-success"))) {
                succBackUrl = actItem.getNotifyURLMap("wx-success") + "?rdseq=" + p_req.rdSeq;
            }
            if (StringHelper.hasAnyChar(actItem.getNotifyURLMap("wx-fail"))) {
                failBackUrl = actItem.getNotifyURLMap("wx-fail") + "?rdseq=" + p_req.rdSeq;
            }
            mapParams.put("SuccBackUrl", succBackUrl);
            mapParams.put("FailBackUrl", failBackUrl);
            mapParams.put("Attach", p_req.attach);
            mapParams.put("DeviceInfo", "");
            mapParams.put("LimitCreditPay", getBankConfig().getValueAsString("limitCreditPay"));
            mapParams.put("OpenId", openId);
            mapParams.put("GoodsTag", "");
            mapParams.put("OrganizationId", p_req.orgId);
            mapParams.put("TimeStart", p_req.timeStart);
            mapParams.put("TimeExpire", p_req.timeExpire);
            mapParams.put("timeout_express", getValidTime(p_req.getValidTime()));

            String isCheckIdentity = "0";
            if ("1".equals(p_req.realNameFlag)) {
                if ("0".equals(p_req.realNameType)) {
                    isCheckIdentity = "3";
                } else if ("2".equals(p_req.realNameType)) {
                    isCheckIdentity = "4";
                } else {
                    isCheckIdentity = "1";
                }
            } else if ("0".equals(p_req.realNameFlag)) {
                isCheckIdentity = "0";
            } else {
                if (StringHelper.hasAnyChar(p_req.oppActName) && StringHelper.hasAnyChar(p_req.certNumber)) {
                    isCheckIdentity = "1";
                }
            }
            mapParams.put("IsCheckIdentity", isCheckIdentity);
            mapParams.put("CertType", convertCertTypeToBank(p_req.certType));
            mapParams.put("CertNum", p_req.certNumber);
            mapParams.put("CustName", p_req.oppActName);
            mapParams.put("PhoneNum", p_req.cellPhone);
            mapParams.put("CallFlag", "00");

            String isRaw = "";
            if (StringHelper.isNullOrEmpty(p_req.isRaw)) {
                if ("".equals(p_req.isRaw)) {
                    isRaw = "0";
                } else {
                    isRaw = getBankConfig().getValueAsString("isRaw");
                    if (StringHelper.isNullOrEmpty(isRaw)) {
                        isRaw = "0";
                    }
                }
            } else {
                isRaw = p_req.isRaw;
            }
            mapParams.put("IsRaw", isRaw);
            mapParams.put("Region", p_req.region);
            mapParams.put("CircPaymentNo", p_req.circPaymentNo);
            mapParams.put("NonceStr", get_nonce_str());

            // 签名
            String signData = getSignStr(mapParams, actItem.saltKey);
            WriteBankLogLn2("待签名数据:\r\n" + signData);

            String isWebAPISign = getBankConfig().getValueAsString("isWebAPISign");
            if ("true".equals(isWebAPISign)) {
                String signature = signWebAPIFnGrd(actItem, signData);
                mapParams.put("Signature", signature);
            } else {
                String signature = signFnGrd(actItem, signData);
                mapParams.put("Signature", signature);
            }

            String reqPostJson = getReqPostJson(mapParams);
            String reqSendData = getReqSendData(actItem.inMerchantId, reqPostJson);

            String[] tmpStrRet = sendToFnGrd(reqSendData, bankFront.getUrl("jsapiWXOrder"));

            if (tmpStrRet[0].length() == 0) {
                if (tmpStrRet[1].indexOf("Status") > 0) {
                    JSONObject respJSON = JSON.parseObject(tmpStrRet[1]);

                    String status = respJSON.getString("Status");
                    if ("-1".equals(status)) {
                        retAts.respCode = "-1";
                        retAts.respInfo = respJSON.getString("ReturnMsg");

                        return retAts;
                    }
                } else {
                    retAts.respCode = "0";
                    retAts.respInfo = "成功";

                    String respStr = getRespPostData(tmpStrRet[1]);

                    JSONObject respJSONObj = JSON.parseObject(respStr);
                    String status = respJSONObj.getString("Status");
                    if ("0".equals(status)) {
                        if ("1".equals(isRaw)) {
                            retAts.qrInfo = respJSONObj.getString("PayUrl");
                        } else if ("0".equals(isRaw)) {
                            JSONObject tmpPayInfo = JSONObject.parseObject(respJSONObj.getString("PayInfo"));
                            retAts.customHashMap = new HashMap<String, String>();
                            retAts.customHashMap.put("appId", tmpPayInfo.getString("appId"));
                            retAts.customHashMap.put("nonceStr", tmpPayInfo.getString("nonceStr"));
                            retAts.customHashMap.put("timeStamp", tmpPayInfo.getString("timeStamp"));
                            retAts.customHashMap.put("package", tmpPayInfo.getString("package"));
                            retAts.customHashMap.put("signType", tmpPayInfo.getString("signType"));
                            retAts.customHashMap.put("paySign", tmpPayInfo.getString("paySign"));
                        }
                    } else {
                        retAts.respCode = "-1";
                        retAts.respInfo = respJSONObj.getString("ReturnMsg");
                    }
                }
            } else {
                retAts.respCode = "-1";
                retAts.respInfo = tmpStrRet[1];
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            retAts.respCode = "-1";
            retAts.respInfo = ex.getMessage();
            WriteBankLogLn(ex);
        }

        return retAts;
    }

    public RetAtsUnifiedOrder submitALIPAYJSAPIOrder(ReqUnifiedOrder p_req) {
        RetAtsUnifiedOrder retAts = new RetAtsUnifiedOrder();
        retAts.rdSeq = p_req.rdSeq;

        try {
            ActSetItem actItem = getBankConfig().getActSetItemByAny(p_req.ownAct, p_req.merchantId, p_req.appId, "unifiedorder");
            if (actItem == null) {
                retAts.respCode = "0";
                retAts.respInfo = "未找到账户[" + p_req.ownAct + "]商户配置信息,请检查config.xml相关配置!";
                retAts.transState = PaymentState.FAIL;
                retAts.payInfoCode = FailCode.E9981;
                return retAts;
            }

            HashMap<String, String> mapParams = new HashMap<String, String>();

            mapParams.put("EnterpriseNum", actItem.inMerchantId);
            mapParams.put("MchId", actItem.merchantId);
            mapParams.put("OutTradeNo", p_req.rdSeq);
            mapParams.put("Body", XmlHelper.encode(p_req.description));
            mapParams.put("TotalFee", StringHelper.amountMultiply100(p_req.amount));
            mapParams.put("NotifyUrl", actItem.notifyURL);
            if (p_req.needReturnURL) {
                mapParams.put("SuccBackUrl", actItem.returnURL);
                mapParams.put("FailBackUrl", actItem.returnURL);
            } else {
                mapParams.put("SuccBackUrl", "");
                mapParams.put("FailBackUrl", "");
            }
            mapParams.put("Attach", p_req.attach);
            mapParams.put("DeviceInfo", "");
            mapParams.put("UserId", p_req.userId);
            mapParams.put("LimitCreditPay", getBankConfig().getValueAsString("limitCreditPay"));
            //mapParams.put("BuyerId", p_req.userId);
            mapParams.put("BuyerLogonId", "");
            mapParams.put("TimeStart", p_req.timeStart);
            mapParams.put("TimeExpire", p_req.timeExpire);
            if ("1".equals(p_req.realNameFlag)) {
                if (StringHelper.hasAnyChar(p_req.circPaymentNo) || StringHelper.hasAnyChar(p_req.region)) {
                    if ("0".equals(p_req.realNameType)) {
                        mapParams.put("IsCheckIdentity", "3");
                    } else if ("2".equals(p_req.realNameType)) {
                        mapParams.put("IsCheckIdentity", "4");
                    } else {
                        mapParams.put("IsCheckIdentity", "2");
                    }
                } else {
                    mapParams.put("IsCheckIdentity", "1");
                }
            } else {
                mapParams.put("IsCheckIdentity", "0");
            }
            mapParams.put("OrganizationId", p_req.orgId);
            mapParams.put("CertType", convertCertTypeToBank(p_req.certType));
            mapParams.put("CertNum", p_req.certNumber);
            mapParams.put("CustName", p_req.oppActName);
            mapParams.put("PhoneNum", p_req.cellPhone);
            mapParams.put("CallFlag", "00");
            mapParams.put("Region", p_req.region);
            mapParams.put("CircPaymentNo", p_req.paymentNo);
            mapParams.put("NonceStr", get_nonce_str());
            mapParams.put("timeout_express", getValidTime(p_req.getValidTime()));

            // 签名
            String signData = getSignStr(mapParams, actItem.saltKey);
            WriteBankLogLn2("待签名数据:\r\n" + signData);

            String signature = signFnGrd(actItem, signData);
            mapParams.put("Signature", signature);

            String reqPostJson = getReqPostJson(mapParams);
            String reqSendData = getReqSendData(actItem.inMerchantId, reqPostJson);

            String[] tmpStrRet = sendToFnGrd(reqSendData, bankFront.getUrl("jsapiALIPAYOrder"));

            if (tmpStrRet[0].length() == 0) {
                if (tmpStrRet[1].indexOf("Status") > 0) {
                    JSONObject respJSON = JSON.parseObject(tmpStrRet[1]);

                    String status = respJSON.getString("Status");
                    if ("-1".equals(status)) {
                        retAts.respCode = "-1";
                        retAts.respInfo = respJSON.getString("ReturnMsg");

                        return retAts;
                    }
                } else {
                    retAts.respCode = "0";
                    retAts.respInfo = "成功";

                    String respStr = getRespPostData(tmpStrRet[1]);

                    JSONObject respJSONObj = JSON.parseObject(respStr);
                    String status = respJSONObj.getString("Status");
                    if ("0".equals(status)) {
                        retAts.customHashMap = new HashMap<String, String>();
                        retAts.customHashMap.put("PayInfo", respJSONObj.getString("PayInfo"));
                        retAts.customHashMap.put("OutTransID", respJSONObj.getString("FGTradeNo"));
                    } else {
                        retAts.respCode = "-1";
                        retAts.respInfo = respJSONObj.getString("ReturnMsg");
                    }
                }
            } else {
                retAts.respCode = "-1";
                retAts.respInfo = tmpStrRet[1];
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            retAts.respCode = "-1";
            retAts.respInfo = ex.getMessage();
            WriteBankLogLn(ex);
        }

        return retAts;
    }

    public RetAtsUnifiedOrder submitMiniProgOrder(ReqUnifiedOrder p_req) {
        RetAtsUnifiedOrder retAts = new RetAtsUnifiedOrder();
        retAts.rdSeq = p_req.rdSeq;

        try {
            ActSetItem actItem = getBankConfig().getActSetItemByAny(p_req.ownAct, p_req.merchantId, p_req.appId, "unifiedorder");
            if (actItem == null) {
                retAts.respCode = "0";
                retAts.respInfo = "未找到账户[" + p_req.ownAct + "]商户配置信息,请检查config.xml相关配置!";
                retAts.transState = PaymentState.FAIL;
                retAts.payInfoCode = FailCode.E9981;
                return retAts;
            }

            HashMap<String, String> mapParams = new HashMap<String, String>();
            String openId = p_req.openid;
            if (StringHelper.isNullOrEmpty(openId)) {
                if (StringHelper.isNullOrEmpty(p_req.code)) {
                    retAts.respCode = "-1";
                    retAts.respInfo = "Code和Openid不能同时为空";

                    return retAts;
                } else {
                    if (StringHelper.isNullOrEmpty(actItem.appSecret)) {
                        retAts.respCode = "-1";
                        retAts.respInfo = "未配置公众号的appsecret";
                        return retAts;
                    } else {
                        HashMap<String, String> hashOpenid = getOpenid(actItem.appId, actItem.appSecret, p_req.code);

                        if (hashOpenid.get("RespCode").equals("0")) {
                            if (hashOpenid.containsKey("openid")) {
                                openId = hashOpenid.get("openid");
                            } else {
                                retAts.respCode = "-1";

                                String errcode = "";
                                if (hashOpenid.containsKey("errcode")) {
                                    errcode = hashOpenid.get("errcode");
                                }

                                String errmsg = "";
                                if (hashOpenid.containsKey("errmsg")) {
                                    errmsg = hashOpenid.get("errmsg");
                                }

                                retAts.respInfo = StringHelper.joinNotEmpty("-", errcode, errmsg);
                                return retAts;
                            }
                        } else {
                            retAts.respCode = "-1";
                            retAts.respInfo = hashOpenid.get("RespInfo");
                            return retAts;
                        }
                    }
                }
            }
            mapParams.put("EnterpriseNum", actItem.inMerchantId);
            mapParams.put("MchId", actItem.merchantId);
            mapParams.put("AppId", actItem.appId);
            mapParams.put("OutTradeNo", p_req.rdSeq);
            mapParams.put("IsMiniPg", "1");
            mapParams.put("Body", XmlHelper.encode(p_req.description));
            mapParams.put("TotalFee", StringHelper.amountMultiply100(p_req.amount));
            mapParams.put("MchCreateIp", actItem.createIP);
            mapParams.put("NotifyUrl", actItem.notifyURL);
            mapParams.put("SuccBackUrl", "");
            mapParams.put("FailBackUrl", "");
            mapParams.put("Attach", p_req.attach);
            mapParams.put("DeviceInfo", "");
            mapParams.put("LimitCreditPay", getBankConfig().getValueAsString("limitCreditPay"));
            mapParams.put("OpenId", openId);
            mapParams.put("GoodsTag", "");
            mapParams.put("OrganizationId", p_req.orgId);
            mapParams.put("TimeStart", p_req.timeStart);
            mapParams.put("TimeExpire", p_req.timeExpire);
            mapParams.put("timeout_express", getValidTime(p_req.getValidTime()));
            if ("1".equals(p_req.realNameFlag)) {
                if (StringHelper.hasAnyChar(p_req.circPaymentNo) || StringHelper.hasAnyChar(p_req.region)) {
                    if ("0".equals(p_req.realNameType)) {
                        mapParams.put("IsCheckIdentity", "3");
                    } else if ("2".equals(p_req.realNameType)) {
                        mapParams.put("IsCheckIdentity", "4");
                    } else {
                        mapParams.put("IsCheckIdentity", "2");
                    }
                } else {
                    mapParams.put("IsCheckIdentity", "1");
                }
            } else {
                mapParams.put("IsCheckIdentity", "0");
            }
            mapParams.put("CertType", convertCertTypeToBank(p_req.certType));
            mapParams.put("CertNum", p_req.certNumber);
            mapParams.put("CustName", p_req.oppActName);
            mapParams.put("PhoneNum", p_req.cellPhone);
            mapParams.put("CallFlag", "00");
            String isRaw = "";
            if (StringHelper.isNullOrEmpty(p_req.isRaw)) {
                if ("".equals(p_req.isRaw)) {
                    isRaw = "0";
                } else {
                    isRaw = getBankConfig().getValueAsString("isRaw");
                    if (StringHelper.isNullOrEmpty(isRaw)) {
                        isRaw = "0";
                    }
                }
            } else {
                isRaw = p_req.isRaw;
            }
            mapParams.put("IsRaw", isRaw);
            mapParams.put("Region", p_req.region);
            mapParams.put("CircPaymentNo", p_req.circPaymentNo);
            mapParams.put("NonceStr", get_nonce_str());
            // 签名
            String signData = getSignStr(mapParams, actItem.saltKey);
            WriteBankLogLn2("待签名数据:\r\n" + signData);

            String isWebAPISign = getBankConfig().getValueAsString("isWebAPISign");
            if ("true".equals(isWebAPISign)) {
                String signature = signWebAPIFnGrd(actItem, signData);
                mapParams.put("Signature", signature);
            } else {
                String signature = signFnGrd(actItem, signData);
                mapParams.put("Signature", signature);
            }

            String reqPostJson = getReqPostJson(mapParams);
            String reqSendData = getReqSendData(actItem.inMerchantId, reqPostJson);

            String[] tmpStrRet = sendToFnGrd(reqSendData, bankFront.getUrl("submitMiniProgOrder"));

            if (tmpStrRet[0].length() == 0) {
                if (tmpStrRet[1].indexOf("Status") > 0) {
                    JSONObject respJSON = JSON.parseObject(tmpStrRet[1]);

                    String status = respJSON.getString("Status");
                    if ("-1".equals(status)) {
                        retAts.respCode = "-1";
                        retAts.respInfo = respJSON.getString("ReturnMsg");

                        return retAts;
                    }
                } else {
                    retAts.respCode = "0";
                    retAts.respInfo = "成功";
                    String respStr = getRespPostData(tmpStrRet[1]);
                    JSONObject respJSONObj = JSON.parseObject(respStr);
                    String status = respJSONObj.getString("Status");
                    if ("0".equals(status)) {
                        if ("1".equals(isRaw)) {
                            retAts.qrInfo = respJSONObj.getString("PayUrl");
                        } else if ("0".equals(isRaw)) {
                            JSONObject tmpPayInfo = JSONObject.parseObject(respJSONObj.getString("PayInfo"));
                            retAts.customHashMap = new HashMap<String, String>();
                            retAts.customHashMap.put("appId", tmpPayInfo.getString("appId"));
                            retAts.customHashMap.put("nonceStr", tmpPayInfo.getString("nonceStr"));
                            retAts.customHashMap.put("timeStamp", tmpPayInfo.getString("timeStamp"));
                            retAts.customHashMap.put("package", tmpPayInfo.getString("package"));
                            retAts.customHashMap.put("signType", tmpPayInfo.getString("signType"));
                            retAts.customHashMap.put("paySign", tmpPayInfo.getString("paySign"));
                        }
                    } else {
                        retAts.respCode = "-1";
                        retAts.respInfo = respJSONObj.getString("ReturnMsg");
                    }
                }
            } else {
                retAts.respCode = "-1";
                retAts.respInfo = tmpStrRet[1];
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            retAts.respCode = "-1";
            retAts.respInfo = ex.getMessage();
            WriteBankLogLn(ex);
        }

        return retAts;
    }

    @Override
    public RetAtsQueryOrder queryJSAPIPay(ReqQueryOrder p_req) {
        RetAtsQueryOrder retAts = new RetAtsQueryOrder();
        retAts.rdSeq = p_req.rdSeq;

        try {
            ActSetItem actItem = this.getBankConfig().getActSetItemByAny(p_req.ownAct, p_req.merchantId, p_req.appId, "unifiedorder");
            if (actItem == null) {
                retAts.respCode = "-1";
                retAts.respInfo = "未找到账户、商户或公众号配置信息,请检查相关配置文件!";
                return retAts;
            }

            HashMap<String, String> mapParams = new HashMap<String, String>();

            mapParams.put("EnterpriseNum", actItem.inMerchantId);
            mapParams.put("MchId", actItem.merchantId);
            mapParams.put("OutTradeNo", p_req.rdSeq);
            mapParams.put("FGTradeNo", "");
            mapParams.put("NonceStr", get_nonce_str());

            String signStr = getSignStr(mapParams, actItem.saltKey);
            String signature = signFnGrd(actItem, signStr);

            mapParams.put("Signature", signature);

            String reqPostJson = getReqPostJson(mapParams);
            String reqSendData = getReqSendData(actItem.inMerchantId, reqPostJson);

            String submitUrl = "";
            if ("WXJSAPI01".equals(p_req.reqHeader.commandCode) || "JSAPI01".equals(p_req.reqHeader.commandCode)) {
                submitUrl = bankFront.getUrl("QueryWXQRPay");
            } else {
                submitUrl = bankFront.getUrl("qyJsapiALIPAYOrder");
            }
            String[] tmpStrRet = sendToFnGrd(reqSendData, submitUrl);

            if (tmpStrRet[0].length() == 0) {
                if (tmpStrRet[1].indexOf("Status") > 0) {
                    JSONObject respJSON = JSON.parseObject(tmpStrRet[1]);

                    String status = respJSON.getString("Status");
                    if ("-1".equals(status)) {
                        retAts.respCode = "-1";
                        retAts.respInfo = respJSON.getString("ReturnMsg");
                        return retAts;
                    }
                } else {
                    String respStr = getRespPostData(tmpStrRet[1]);

                    JSONObject respJSONObj = JSON.parseObject(respStr);

                    String status = respJSONObj.getString("Status");

                    retAts.respCode = "0";
                    retAts.respInfo = respJSONObj.getString("ReturnMsg");

                    if ("0".equals(status)) {
                        retAts.transState = StringHelper.joinNotEmpty("+", status, respJSONObj.getString("TradeState"));
                        retAts.payInfoCode = respJSONObj.getString("TradeState");

                        String outTransID = respJSONObj.getString("Transaction_id");
                        if (StringHelper.isNullOrEmpty(outTransID)) {
                            outTransID = respJSONObj.getString("BankBillNo");
                        }
                        retAts.outTransID = outTransID;
                        retAts.oppBank = respJSONObj.getString("BankType");
                        retAts.openId = respJSONObj.getString("OpenId");
                    } else {
                        retAts.transState = StringHelper.joinNotEmpty("+", status, respJSONObj.getString("ReturnMsg"));
                        retAts.payInfoCode = respJSONObj.getString("ReturnMsg");
                    }
                }
            } else {
                retAts.respCode = "-1";
                retAts.respInfo = tmpStrRet[1];
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            retAts.respCode = "-1";
            retAts.respInfo = ex.getMessage();
            WriteBankLogLn(ex);
        }

        return retAts;
    }

    @Override
    public RetAtsGenGetUserCodeURL GenGetUserCodeURL(ReqGenGetUserCodeURL p_req) {
        RetAtsGenGetUserCodeURL retAts = new RetAtsGenGetUserCodeURL();

        try {
            ActSetItem actItem = this.getBankConfig().getActSetItem(p_req.ownAct, "getUserId");
            if (actItem == null) {
                actItem = this.getBankConfig().getActSetItem(p_req.ownAct, "unifiedorder");
            }
            if (actItem != null) {
                String authUrl = bankFront.getUrl("authUrl"); // 授权URL
                WriteBankLogLn2("authUrl: " + authUrl);

                if (StringHelper.hasAnyChar(authUrl)) {
                    String authRedirectUri = p_req.authRedirectUri;
                    if (StringHelper.isNullOrEmpty(authRedirectUri)) {
                        authRedirectUri = bankFront.getUrl("authRedirectUri");// 支付宝授权回调地址
                    }
                    WriteBankLogLn2("authRedirectUri: " + authRedirectUri);
                    if (StringHelper.hasAnyChar(authRedirectUri)) {
                        retAts.respCode = "0";
                        retAts.respInfo = "成功";
                        retAts.getUserCodeURL = authUrl + "?appid=" + actItem.appId + "&redirect_uri=" + URLEncoder.encode(authRedirectUri, getCharset()) + "&attach=" + p_req.urid;
                    } else {
                        retAts.respCode = "-1";
                        retAts.respInfo = "未找到授权回调地址!";
                    }
                } else {
                    retAts.respCode = "-1";
                    retAts.respInfo = "未找到授权URL!";
                }
            } else {
                retAts.respCode = "-1";
                retAts.respInfo = "未找到账号[" + p_req.ownAct + "]商户配置信息!";
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            retAts.respCode = "-1";
            retAts.respInfo = ex.getMessage();
            WriteBankLogLn(ex);
        }

        return retAts;
    }

    @Override
    public RetAtsGenGetUserCodeURL getUserId(ReqGenGetUserCodeURL p_req) {
        RetAtsGenGetUserCodeURL retAts = new RetAtsGenGetUserCodeURL();

        try {
            ActSetItem actItem = getBankConfig().getActSetItem(p_req.ownAct, "unifiedorder");
            if (actItem != null) {
                AlipayClient alipayClient = new DefaultAlipayClient(bankFront.serverURL, actItem.appId,
                        actItem.ownKeyStorePath, "json", getCharset(), actItem.oppCertFilePath, "RSA2");

                AlipaySystemOauthTokenRequest alipayRequest = new AlipaySystemOauthTokenRequest();

                alipayRequest.setGrantType("authorization_code");
                alipayRequest.setCode(p_req.code);

                WriteBankUrlLogLn(bankFront.serverURL);

                AlipaySystemOauthTokenResponse response = alipayClient.execute(alipayRequest);
                WriteBankLogStep3(response.getBody());

                retAts.respCode = "0";
                retAts.respInfo = response.getMsg();
                if (StringHelper.isNullOrEmpty(response.getCode())) {
                    retAts.userId = response.getUserId();
                } else {
                    retAts.respCode = "-1";
                    retAts.respInfo = StringHelper.joinNotEmpty("-", response.getSubCode(), response.getSubMsg());
                }
            } else {
                retAts.respCode = "-1";
                retAts.respInfo = "未找到账号[" + p_req.ownAct + "]商户配置信息!";
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            retAts.respCode = "-1";
            retAts.respInfo = ex.getMessage();
            WriteBankLogLn(ex);
        }

        return retAts;
    }

    @Override
    public RetAtsGenRealNameURL genRealNameURL(ReqGenRealNameURL p_req) {
        return null;
    }
}